package com.k8sops.backend.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.k8sops.backend.common.BusinessException;
import com.k8sops.backend.entity.Cluster;
import com.k8sops.backend.entity.Namespace;
import com.k8sops.backend.mapper.NamespaceMapper;
import com.k8sops.backend.service.ClusterService;
import com.k8sops.backend.service.NamespaceService;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1Namespace;
import io.kubernetes.client.openapi.models.V1NamespaceList;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
import io.kubernetes.client.util.Config;
import io.kubernetes.client.util.KubeConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class NamespaceServiceImpl extends ServiceImpl<NamespaceMapper, Namespace> implements NamespaceService {

    @Autowired
    private ClusterService clusterService;

    @Override
    public List<Namespace> listNamespacesByClusterId(Long clusterId) {
        LambdaQueryWrapper<Namespace> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Namespace::getClusterId, clusterId);
        wrapper.eq(Namespace::getDeleted, 0);
        wrapper.orderByAsc(Namespace::getName);
        return list(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean syncNamespaces(Long clusterId) {
        Cluster cluster = clusterService.getById(clusterId);
        if (cluster == null) {
            throw new BusinessException("集群不存在");
        }
        
        try {
            // 获取K8s客户端
            ApiClient client = getApiClient(cluster.getKubeConfig());
            CoreV1Api api = new CoreV1Api(client);
            
            // 获取集群中的命名空间列表
            V1NamespaceList namespaceList = api.listNamespace(null, null, null, null, null, null, null, null, null, null);
            
            // 先将数据库中该集群的所有命名空间标记为已删除
            LambdaQueryWrapper<Namespace> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Namespace::getClusterId, clusterId);
            List<Namespace> existNamespaces = list(wrapper);
            for (Namespace existNamespace : existNamespaces) {
                existNamespace.setDeleted(1);
                existNamespace.setUpdateTime(LocalDateTime.now());
                updateById(existNamespace);
            }
            
            // 同步集群中的命名空间到数据库
            for (V1Namespace v1Namespace : namespaceList.getItems()) {
                String name = v1Namespace.getMetadata().getName();
                String status = v1Namespace.getStatus().getPhase();
                Map<String, String> labels = v1Namespace.getMetadata().getLabels();
                Map<String, String> annotations = v1Namespace.getMetadata().getAnnotations();
                
                // 查询数据库中是否已存在该命名空间
                LambdaQueryWrapper<Namespace> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Namespace::getClusterId, clusterId);
                queryWrapper.eq(Namespace::getName, name);
                Namespace namespace = getOne(queryWrapper);
                
                if (namespace == null) {
                    // 不存在则新增
                    namespace = new Namespace();
                    namespace.setClusterId(clusterId);
                    namespace.setName(name);
                    namespace.setStatus(status);
                    namespace.setLabels(labels != null ? JSON.toJSONString(labels) : null);
                    namespace.setAnnotations(annotations != null ? JSON.toJSONString(annotations) : null);
                    namespace.setCreateTime(LocalDateTime.now());
                    namespace.setUpdateTime(LocalDateTime.now());
                    namespace.setDeleted(0);
                    save(namespace);
                } else {
                    // 存在则更新
                    namespace.setStatus(status);
                    namespace.setLabels(labels != null ? JSON.toJSONString(labels) : null);
                    namespace.setAnnotations(annotations != null ? JSON.toJSONString(annotations) : null);
                    namespace.setUpdateTime(LocalDateTime.now());
                    namespace.setDeleted(0);
                    updateById(namespace);
                }
            }
            
            return true;
        } catch (ApiException | IOException e) {
            log.error("同步命名空间失败", e);
            throw new BusinessException("同步命名空间失败：" + e.getMessage());
        }
    }

    @Override
    public boolean createNamespace(Namespace namespace) {
        Cluster cluster = clusterService.getById(namespace.getClusterId());
        if (cluster == null) {
            throw new BusinessException("集群不存在");
        }
        
        try {
            // 获取K8s客户端
            ApiClient client = getApiClient(cluster.getKubeConfig());
            CoreV1Api api = new CoreV1Api(client);
            
            // 创建命名空间对象
            V1Namespace v1Namespace = new V1Namespace();
            V1ObjectMeta meta = new V1ObjectMeta();
            meta.setName(namespace.getName());
            
            // 设置标签
            if (namespace.getLabels() != null) {
                Map<String, String> labels = JSON.parseObject(namespace.getLabels(), new com.alibaba.fastjson.TypeReference<Map<String, String>>(){});
                meta.setLabels(labels);
            }
            
            // 设置注释
            if (namespace.getAnnotations() != null) {
                Map<String, String> annotations = JSON.parseObject(namespace.getAnnotations(), new com.alibaba.fastjson.TypeReference<Map<String, String>>(){});
                meta.setAnnotations(annotations);
            }
            
            v1Namespace.setMetadata(meta);
            
            // 调用K8s API创建命名空间
            api.createNamespace(v1Namespace, null, null, null, null);
            
            // 保存到数据库
            namespace.setStatus("Active");
            namespace.setCreateTime(LocalDateTime.now());
            namespace.setUpdateTime(LocalDateTime.now());
            namespace.setDeleted(0);
            save(namespace);
            
            return true;
        } catch (ApiException | IOException e) {
            log.error("创建命名空间失败", e);
            throw new BusinessException("创建命名空间失败：" + e.getMessage());
        }
    }

    @Override
    public boolean deleteNamespace(Long clusterId, String name) {
        Cluster cluster = clusterService.getById(clusterId);
        if (cluster == null) {
            throw new BusinessException("集群不存在");
        }
        
        try {
            // 获取K8s客户端
            ApiClient client = getApiClient(cluster.getKubeConfig());
            CoreV1Api api = new CoreV1Api(client);
            
            // 调用K8s API删除命名空间
            api.deleteNamespace(name, null, null, null, null, null, null);
            
            // 更新数据库记录
            LambdaQueryWrapper<Namespace> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Namespace::getClusterId, clusterId);
            wrapper.eq(Namespace::getName, name);
            Namespace namespace = getOne(wrapper);
            
            if (namespace != null) {
                namespace.setDeleted(1);
                namespace.setUpdateTime(LocalDateTime.now());
                updateById(namespace);
            }
            
            return true;
        } catch (ApiException | IOException e) {
            log.error("删除命名空间失败", e);
            throw new BusinessException("删除命名空间失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取K8s API客户端
     * @param kubeConfig 集群配置
     * @return API客户端
     * @throws IOException IO异常
     */
    private ApiClient getApiClient(String kubeConfig) throws IOException {
        // 解码Base64编码的kubeConfig
        byte[] decodedBytes = Base64.getDecoder().decode(kubeConfig);
        String decodedConfig = new String(decodedBytes, StandardCharsets.UTF_8);
        
        // 使用KubeConfig加载配置
        KubeConfig config = KubeConfig.loadKubeConfig(new InputStreamReader(
                new ByteArrayInputStream(decodedConfig.getBytes(StandardCharsets.UTF_8))));
        return Config.fromConfig(config);
    }
}
